/**
 * @file: main.c
 * @brief: 处理通信中的不同状态
 * @author: 廖文雄 
 * @date: 2019.07.27
 * @note: 
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <malloc.h>

#include "communication.h"

int main()
{
    int is_break_outside = FALSE;
    int state = BAG_REVICE;
    int bag_type = REQUEST;
    char *send_data;
    char *get_data = (char *)malloc(BAG_DATA * sizeof(char));
    int fifo_fd;
    int is_rdwr_success;
    int is_revice_success;
    int is_verify;

    while (is_break_outside != TRUE) {
        switch (state) {
            case BAG_BUILD :
                send_data = build_data(bag_type);
                if (!send_data) {
                    break;
                } else {
                    state = BAG_SEND;
                    break;
                }
            case BAG_SEND :
                fifo_fd = open(FIFO_NAME, O_WRONLY);
                if (fifo_fd == FALSE) {
                    printf("can't open fifo\n");
                    break;
                }
                is_rdwr_success = write(fifo_fd, send_data,
                                    strlen(send_data));
                if (is_rdwr_success == FALSE) {
                    printf("send error\n");
                    close(fifo_fd);
                    break;
                } else {
                    free(send_data);
                    close(fifo_fd);
                    if (bag_type == ACK_DATA) {
                        is_break_outside = TRUE;
                        break;
                    }

                    state = BAG_REVICE;
                    break;
                }
            case BAG_REVICE :
                fifo_fd = open(FIFO_NAME, O_RDONLY);
                if (fifo_fd == FALSE) {
                    printf("can't open fifo\n");
                    break;
                }
                /* 在发送响应包、数据接收失败或成功后，接收数据包 */
                /* 其他情况接收命令包 */
                if (bag_type == RESPONSE || bag_type == FALSE_DATA ||
                    bag_type == ACK_DATA) {
                    is_rdwr_success = read(fifo_fd, get_data, BAG_DATA);
                } else {
                    is_rdwr_success = read(fifo_fd, get_data, BAG_COMMOND);
                }
                if (is_rdwr_success == FALSE) {
                    printf("revice error\n");
                    close(fifo_fd);
                    break;
                } else {
                    close(fifo_fd);

                    state = BAG_ANALYSIS;
                    break;
                }
            /* 这个和状态转换有关,需要根据自己的状态转换和逻辑来写 */
            case BAG_ANALYSIS :
                is_verify = analysis_verify(get_data);
                if (is_verify == FALSE) {
                    /* 请求包接收失败 */
                    if (bag_type == REQUEST) {
                        bag_type = FALSE_REQUEST;
                    } else if (bag_type == RESPONSE) {
                        /* 数据接收失败，发送数据接收失败的指令 */
                        bag_type = FALSE_DATA;
                    }

                    state = BAG_BUILD;
                    break;
                }

                is_revice_success = analysis_data(get_data);
                if (is_revice_success == FALSE) {
                    /* 请求包接收失败,发送请求包失败命令 */
                    if (bag_type == REQUEST) {
                        bag_type = FALSE_REQUEST;
                    }

                    /* 数据接收失败，发送数据接收失败的指令 */
                    if (bag_type == RESPONSE) {
                        bag_type = FALSE_DATA;
                    }

                    state = BAG_BUILD;
                    break;
                } else {
                    /* 请求包接收成功,发送应答包 */
                    if (bag_type == REQUEST) {
                        if (is_revice_success == REQUEST) {
                            bag_type = RESPONSE;
                        }
                    }

                    /* 数据接收成功，发送数据接收成功的指令 */
                    if (bag_type == RESPONSE) {
                        if (is_revice_success == PRINT_NORMAL) {
                            bag_type = ACK_DATA;
                        }
                    }

                    state = BAG_BUILD;
                    break;
                }
            case FINISH :
                is_break_outside = TRUE;
                break;
        }
    }

    return 1;
}